class TeListener<T = undefined, T0 = undefined, T1 = undefined, T2 = undefined> {
  id: any
  event: Map<string, any>
  v0: any
  v1: any
  v2: any
  v: any
  constructor(t?: T, t0?: T0, t1?: T1, t2?: T2) {
    this.id = -1
    this.event = new Map<string, any>()
    this.v = t
    this.v0 = t0
    this.v1 = t1
    this.v2 = t2
  }

  get count() {
    return this.event.size
  }

  _getKey(fun: { name: any }, n: string) {
    let s = '' + n ? n : ''
    s += fun.name
    return s
  }

  add(fun: any, n: any) {
    if (!fun) return this
    this.event.set(this._getKey(fun, n), fun)
    return this
  }

  addDoStart(fun: any, n: any) {
    if (!fun) return this
    this.event.set(this._getKey(fun, n), fun)
    fun(this.v, this.v0, this.v1, this.v2)
    return this
  }

  remove(fun: any, n: any) {
    if (!fun) return
    this.event.delete(this._getKey(fun, n))
  }

  fireT(t: T) {
    this.v = t
    for (const fun of this.event.values()) fun(t)
  }
  fireTT(t: T, t0: T0) {
    for (const fun of this.event.values()) fun(t, t0)
    this.v = t
    this.v0 = t0
  }
  fireTTT(t: T, t0: T0, t1: T1) {
    for (const fun of this.event.values()) fun(t, t0, t1)
    this.v = t
    this.v0 = t0
    this.v1 = t1
  }

  fireTTTT(t: T, t0: T0, t1: T1, t2: T2) {
    for (const fun of this.event.values()) fun(t, t0, t1, t2)
    this.v = t
    this.v0 = t0
    this.v1 = t1
    this.v2 = t2
  }

  fire(...args: any[]) {
    this.v = args
    for (const fun of this.event.values()) {
      fun(...args)
    }
  }

  doOne() {
    this.fireTTTT(this.v, this.v0, this.v1, this.v2)
  }
}

class TeCall<T>{
  id: any
  private _fun?: (v: T) => any
  private _v: any
  constructor(t: T) {
    this.id = -1
    this._v = t
  }

  setCall(fun: (v: T) => any) {
    this._fun = fun
    this._fun(this._v)
  }

  set v(v: T) {
    if (v === this._v) return
    this._v = v
    this._fun?.(v)
  }
  get v() {
    return this._v
  }
}
export { TeListener, TeCall }
